/*
 * swTWI.h
 *
 *  Created on: 01-09-2014
 *      Author: Roper123pl
 *
 *  based on: Arduino Wire library
 */

#ifndef SWTWI_H_
#define SWTWI_H_

#include <Arduino.h>


#define BUFFER_LENGTH 32

#define swTWI_SPEED_FAST 3		// TWI clock ~100kHz for Arduino328P 16MHz 5V
#define swTWI_SPEED_NORMAL 5	// TWI clock ~75kHz
#define swTWI_SPEED_MEDIUM 9	// TWI clock ~50kHz
#define swTWI_SPEED_SLOW 19		// TWI clock ~25kHz

// Bit to or with address for read
uint8_t const swTWI_READ = 1;
// Bit to or with address for write
uint8_t const swTWI_WRITE = 0;

class swTWI {

  public:
	swTWI();
	uint8_t begin(uint8_t sdaPin, uint8_t sclPin);
	uint8_t begin(uint8_t sdaPin, uint8_t sclPin, uint8_t speed);
	void setSpeed(uint8_t speed);
	void beginTransmission(uint8_t address);
	void beginTransmission(int address);
	uint8_t endTransmission(void);
	uint8_t endTransmission(uint8_t sendStop);
	uint8_t requestFrom(uint8_t address, uint8_t quantity);
	uint8_t requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop);
	uint8_t requestFrom(int address, int quantity);
	uint8_t requestFrom(int address, int quantity, int sendStop);
	uint8_t write(uint8_t data);
	uint8_t write(const uint8_t * data, size_t quantity);
	int available(void);
	int read(void);

  private:
	uint8_t	_twiDelay;

	uint8_t _sdaBit;
	uint8_t _sdaPort;
	volatile uint8_t* _sdaMode;
	volatile uint8_t* _sdaOut;
	volatile uint8_t* _sdaIn;

	uint8_t _sclBit;
	uint8_t _sclPort;
	volatile uint8_t* _sclMode;
	volatile uint8_t* _sclOut;
	volatile uint8_t* _sclIn;

	uint8_t* _buffer;					// transmission data buffer
	uint8_t _bufferIndex;				// buffer pointer
	uint8_t _bufferLength;				// buffer length

	uint8_t _devAddr;					// slave device address

	uint8_t _transmitting;				// transmission flag

	void _sendStart(void);
	void _sendStop(void);
	void _sendRestart(void);

	uint8_t _read(void);
	uint8_t _read(uint8_t sendAck);
	uint8_t _read(uint8_t* buffer, uint8_t quantity);
	uint8_t _write(uint8_t data);
	uint8_t _write(uint8_t* buffer, uint8_t quantity);
};


/*
 *  Preinstantiate Objects
 */
extern swTWI swWire;

#endif /* SWTWI_H_ */

